package csci5115.autoalarm;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import csci5115.autoalarm.MyLocation;
import csci5115.autoalarm.MyLocation.LocationResult;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.RelativeLayout;

public class MapsActivity extends MapActivity  {
	ListView lvwDrivingInstructions;
    MapView mapView;
    Button btnDrivingInstructions, btnMap;
         
    boolean blnMapLoaded = false, blnDirectionsLoaded = false;
    // Source will be the user's current location
    double src_lat =0 , src_long = 0, dest_lat=44.9745649, dest_long=-93.272623;
  
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.maps);
  
        btnDrivingInstructions = (Button) findViewById(R.id.btnDrivingInstructions);
        btnMap = (Button) findViewById(R.id.btnMap);
      
        Bundle extras = getIntent().getExtras();
        if(extras !=null)
        {
             //String EventID = extras.getString("EventID");
        }

        try {
            MyLocation my_location = new MyLocation();
            my_location.init(this, locationResult);
            
            blnMapLoaded = true;
          
            btnDrivingInstructions.setOnClickListener(new View.OnClickListener() {
              
                public void onClick(View v) {
                	if (blnDirectionsLoaded == false){
                	    String url = getUrl(src_lat + "," + src_long, dest_lat + "," +  dest_long);
                		
                	    InputStream is = null;	        
                    	try {
                    		HttpClient httpclient = new DefaultHttpClient();
                            HttpPost httppost = new HttpPost(url);
                            HttpResponse response;
                            
                			response = httpclient.execute(httppost);
                	        HttpEntity entity = response.getEntity();
                	        is = entity.getContent();	            
                	        
                	        String resultString = convertStreamToString(is);    
                	                       
                	        try {
                	        	JSONObject rootObj = new JSONObject(resultString);
                	        	JSONArray routes = (JSONArray) rootObj.get("routes");
                	        	if(routes.length()>=1){
                					JSONObject firstRoute = routes.getJSONObject(0);
                		            JSONArray legs = (JSONArray) firstRoute.get("legs");
                		            if(legs.length()>=1){
                			            JSONObject firstLeg = legs.getJSONObject(0);
                			            //JSONObject durationObject = (JSONObject) firstLeg.get("duration");
                			            //JSONObject distanceObject = (JSONObject) firstLeg.get("distance");
                			            
                			            // finally we will get the values distance in meters and time in seconds!!
                			            //Integer timeToDestination = (Integer) durationObject.get("value");
                			            //Integer distanceToDestination = (Integer) distanceObject.get("value");
                			            
                			            JSONArray steps = (JSONArray) firstLeg.get("steps");
                			            int numSteps = steps.length();
                			            
                			            ArrayList<Directions> searchDirections = new ArrayList<Directions>();		

                			            for (int i = 0; i < numSteps; i++) {
                			                //Get the individual step
                			                final JSONObject step = steps.getJSONObject(i);
                			                //Set the length of this segment in metres
                			                String strDistance = step.getJSONObject("distance").getString("text");
                			                String strDuration = step.getJSONObject("duration").getString("text");
                			                
                			                //Strip html from google directions and set as turn instruction
                			                //int stt = i + 1;
                			                
                			                Directions clsStep = new Directions();
                			                clsStep.setInstructions(step.getString("html_instructions").replaceAll("<(.*?)*>", ""));
                			                clsStep.setDuration(strDistance + " " + strDuration);
                			                searchDirections.add(clsStep);
                			        	}	                            			            	                         
                			            
                			            lvwDrivingInstructions = (ListView) findViewById(R.id.lvwDrivingInstructions);
                			            lvwDrivingInstructions.setAdapter(new DirectionsAdapter(v.getContext(), searchDirections));
                		            }  		
                	        	}
                	        } catch (JSONException e) {
                	        	// TODO Auto-generated catch block
                	            e.printStackTrace();
                	        }
                		} catch (ClientProtocolException e) {
                			// TODO Auto-generated catch block
                			e.printStackTrace();
                		} catch (IOException e) {
                			// TODO Auto-generated catch block
                			e.printStackTrace();
                		}      
                	}    
            		RelativeLayout Layout1 = (RelativeLayout)findViewById(R.id.layout1);
            		RelativeLayout Layout2 = (RelativeLayout)findViewById(R.id.layout2);

            		// Enable Layout 2 and Disable Layout 1
            		Layout1 .setVisibility(View.VISIBLE);
            		Layout2.setVisibility(View.GONE);
                }
            });
            
            btnMap.setOnClickListener(new View.OnClickListener() {
                
                public void onClick(View v) {
            		RelativeLayout Layout1 = (RelativeLayout)findViewById(R.id.layout1);
            		RelativeLayout Layout2 = (RelativeLayout)findViewById(R.id.layout2);

            		// Enable Layout 2 and Disable Layout 1
            		Layout1 .setVisibility(View.GONE);
            		Layout2.setVisibility(View.VISIBLE);      
                }
            });
		} catch (Exception e) {
			// TODO: handle exception
		}
    }
  
    public LocationResult locationResult = new LocationResult(){
        @Override
        public void gotLocation(final Location location){           
            mapView = (MapView) findViewById(R.id.mapView);
            mapView.setBuiltInZoomControls(true);
                     
            src_lat = location.getLatitude();
            src_long  = location.getLongitude();
          
            if  (src_lat != 0 && src_long != 0)
            {
                GeoPoint srcGeoPoint = new GeoPoint ((int) (src_lat * 1E6),
                (int) (src_long * 1E6));
                GeoPoint destGeoPoint = new GeoPoint((int) (dest_lat * 1E6),
                (int) (dest_long * 1E6));
              
                DrawPath(srcGeoPoint, destGeoPoint, Color.GREEN, mapView);
              
                mapView.getController().animateTo(srcGeoPoint);
                mapView.getController().setZoom(15);
            }    
        }
   };
    
    private void DrawPath(GeoPoint src,GeoPoint dest, int color, MapView mMapView01)
    {
        // connect to map web service
        StringBuilder urlString = new StringBuilder();
        urlString.append("http://maps.google.com/maps?f=d&hl=en");
        urlString.append("&saddr=");//from
        urlString.append( Double.toString((double)src.getLatitudeE6()/1.0E6 ));
        urlString.append(",");
        urlString.append( Double.toString((double)src.getLongitudeE6()/1.0E6 ));
        urlString.append("&daddr=");//to
        urlString.append( Double.toString((double)dest.getLatitudeE6()/1.0E6 ));
        urlString.append(",");
        urlString.append( Double.toString((double)dest.getLongitudeE6()/1.0E6 ));
      
        urlString.append("&ie=UTF8&0&om=0&output=kml");
        Log.d("xxx","URL="+urlString.toString());
      
        // get the kml (XML) doc. And parse it to get the coordinates(direction route).
        Document doc = null;
        HttpURLConnection urlConnection= null;
        URL url = null;
        try
        {
            url = new URL(urlString.toString());
            urlConnection=(HttpURLConnection)url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setDoOutput(true);
            urlConnection.setDoInput(true);
            urlConnection.connect();
      
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            doc = db.parse(urlConnection.getInputStream());
  
        if(doc.getElementsByTagName("GeometryCollection").getLength()>0)
        {
            String path = doc.getElementsByTagName("GeometryCollection").item(0).getFirstChild().getFirstChild().getFirstChild().getNodeValue() ;
            Log.d("xxx","path="+ path);
            String [] pairs = path.split(" ");
            String[] lngLat = pairs[0].split(","); // lngLat[0]=longitude lngLat[1]=latitude lngLat[2]=height
            // src
            GeoPoint startGP = new GeoPoint((int)(Double.parseDouble(lngLat[1])*1E6),(int)(Double.parseDouble(lngLat[0])*1E6));
            mMapView01.getOverlays().add(new MyOverlay(startGP,startGP,1));
            GeoPoint gp1;
            GeoPoint gp2 = startGP;
          
            for(int i=1;i<pairs.length;i++) // the last one would be crash
            {
                lngLat = pairs[i].split(",");
                gp1 = gp2;
                // watch out! For GeoPoint, first:latitude, second:longitude
                gp2 = new GeoPoint((int)(Double.parseDouble(lngLat[1])*1E6),(int)(Double.parseDouble(lngLat[0])*1E6));
                mMapView01.getOverlays().add(new MyOverlay(gp1,gp2,2,color));
                Log.d("xxx","pair:" + pairs[i]);
            }
          
            mMapView01.getOverlays().add(new MyOverlay(dest,dest, 3)); // use the default color
        }
        }
        catch (MalformedURLException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (ParserConfigurationException e)
        {
            e.printStackTrace();
        }
        catch (SAXException e)
        {
            e.printStackTrace();
        }
    }

    public static JSONObject getLocationInfo(String address) {
        StringBuilder stringBuilder = new StringBuilder();
        try {

        address = address.replaceAll(" ","%20");  

        HttpPost httppost = new HttpPost("http://maps.google.com/maps/api/geocode/json?address=" + address + "&sensor=false");
        HttpClient client = new DefaultHttpClient();
        HttpResponse response;
        stringBuilder = new StringBuilder();


            response = client.execute(httppost);
            HttpEntity entity = response.getEntity();
            InputStream stream = entity.getContent();
            int b;
            while ((b = stream.read()) != -1) {
                stringBuilder.append((char) b);
            }
        } catch (ClientProtocolException e) {
        } catch (IOException e) {
        }

        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject = new JSONObject(stringBuilder.toString());
        } catch (JSONException e) {
            e.printStackTrace();
        }

        return jsonObject;
    }

	private static String convertStreamToString(InputStream input) {
	    BufferedReader reader = new BufferedReader(new InputStreamReader(input));
	    StringBuilder sBuf = new StringBuilder();
	
	    String line = null;
	    try {
	    	while ((line = reader.readLine()) != null) {
	            sBuf.append(line);
	        }
	    } catch (IOException e) {
	        e.printStackTrace();
	    } finally {
	        try {
	            input.close();
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	    }
	    return sBuf.toString();
	}
	
	  
	  // String Builder for Google Maps JSON will create the Link for the google maps query based on the entered data
	  public static String getUrl(String fromAdress, String toAdress) {// connect to map web service
		  StringBuffer urlString = new StringBuffer();
		  urlString.append("http://maps.google.com/maps/api/directions/json?origin=");
		  urlString.append(fromAdress.toString());
		  urlString.append("&destination=");
		  urlString.append(toAdress.toString());
		  urlString.append("&sensor=false");
		  return urlString.toString().replace(" ", "%20");
	  }// end getUrl
	  
    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
}